Tegra186: read activity monitor's clock counter values
authorVarun Wadekar <[email protected]>
Fri, 23 Sep 2016 21:28:16 +0000 (14:28 -0700)
committerVarun Wadekar <[email protected]>
Fri, 7 Apr 2017 16:15:51 +0000 (09:15 -0700)
This patch adds a new SMC function ID to read the refclk and coreclk
clock counter values from the Activity Monitor. The non-secure world
requires this information to calculate the CPU's frequency.

Formula: "freq = (delta_coreclk / delta_refclk) * refclk_freq"

The following CPU registers have to be set by the non-secure driver
before issuing the SMC:

X1 = MPIDR of the target core
X2 = MIDR of the target core

Change-Id: I296d835def1f5788c17640c0c456b8f8f0e90824
Signed-off-by: Varun Wadekar <[email protected]>
plat/nvidia/tegra/include/t186/tegra_def.h
plat/nvidia/tegra/soc/t186/plat_setup.c
plat/nvidia/tegra/soc/t186/plat_sip_calls.c
plat/nvidia/tegra/soc/t186/platform_t186.mk

index 4c99a7b0483bf3d936e3ff3fea0b9180673b489c..f919ac378e814fa090a81ff0745f2ae713fbe407 100644 (file)
 #define  SECURE_SCRATCH_RSV55_HI       0x80C
 
 /*******************************************************************************
- * Tegra Memory Mapped Control Register Access Bus constants
+ * Tegra Memory Mapped Control Register Access constants
  ******************************************************************************/
 #define TEGRA_MMCRAB_BASE              0x0E000000
 
+/*******************************************************************************
+ * Tegra Memory Mapped Activity Monitor Register Access constants
+ ******************************************************************************/
+#define TEGRA_ARM_ACTMON_CTR_BASE      0x0E060000
+#define TEGRA_DENVER_ACTMON_CTR_BASE   0x0E070000
+
 /*******************************************************************************
  * Tegra SMMU Controller constants
  ******************************************************************************/
index e848eabb7e737667463ed6ebfd71b929204207bb..c401b858f45afa7218f4c3eda1d589568824132a 100644 (file)
@@ -102,6 +102,8 @@ static const mmap_region_t tegra_mmap[] = {
                        MT_DEVICE | MT_RW | MT_SECURE),
        MAP_REGION_FLAT(TEGRA_MMCRAB_BASE, 0x60000, /* 384KB */
                        MT_DEVICE | MT_RW | MT_SECURE),
+       MAP_REGION_FLAT(TEGRA_ARM_ACTMON_CTR_BASE, 0x20000, /* 128KB - ARM/Denver */
+                       MT_DEVICE | MT_RW | MT_SECURE),
        MAP_REGION_FLAT(TEGRA_SMMU_BASE, 0x1000000, /* 64KB */
                        MT_DEVICE | MT_RW | MT_SECURE),
        {0}
index 31e903eba91d44efdf93b8b24a099486813b0fd6..fa3974972e551ca01fb5271abfde1f12e4c24250 100644 (file)
@@ -34,6 +34,7 @@
 #include <bl_common.h>
 #include <context_mgmt.h>
 #include <debug.h>
+#include <denver.h>
 #include <errno.h>
 #include <mce.h>
 #include <memctrl.h>
 
 extern uint32_t tegra186_system_powerdn_state;
 
+/*******************************************************************************
+ * Offset to read the ref_clk counter value
+ ******************************************************************************/
+#define REF_CLK_OFFSET         4
+
 /*******************************************************************************
  * Tegra186 SiP SMCs
  ******************************************************************************/
-#define TEGRA_SIP_NEW_VIDEOMEM_REGION                  0x82000003
 #define TEGRA_SIP_SYSTEM_SHUTDOWN_STATE                        0x82FFFE01
+#define TEGRA_SIP_GET_ACTMON_CLK_COUNTERS              0x82FFFE02
 #define TEGRA_SIP_MCE_CMD_ENTER_CSTATE                 0x82FFFF00
 #define TEGRA_SIP_MCE_CMD_UPDATE_CSTATE_INFO           0x82FFFF01
 #define TEGRA_SIP_MCE_CMD_UPDATE_CROSSOVER_TIME                0x82FFFF02
@@ -81,6 +87,8 @@ int plat_sip_handler(uint32_t smc_fid,
                     uint64_t flags)
 {
        int mce_ret;
+       int impl, cpu;
+       uint32_t base, core_clk_ctr, ref_clk_ctr;
 
        switch (smc_fid) {
 
@@ -143,6 +151,36 @@ int plat_sip_handler(uint32_t smc_fid,
 
                return 0;
 
+       /*
+        * This function ID reads the Activity monitor's core/ref clock
+        * counter values for a core/cluster.
+        *
+        * x1 = MPIDR of the target core
+        * x2 = MIDR of the target core
+        */
+       case TEGRA_SIP_GET_ACTMON_CLK_COUNTERS:
+
+               cpu = (uint32_t)x1 & MPIDR_CPU_MASK;
+               impl = ((uint32_t)x2 >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
+
+               /* sanity check target CPU number */
+               if (cpu > PLATFORM_MAX_CPUS_PER_CLUSTER)
+                       return -EINVAL;
+
+               /* get the base address for the current CPU */
+               base = (impl == DENVER_IMPL) ? TEGRA_DENVER_ACTMON_CTR_BASE :
+                       TEGRA_ARM_ACTMON_CTR_BASE;
+
+               /* read the clock counter values */
+               core_clk_ctr = mmio_read_32(base + (8 * cpu));
+               ref_clk_ctr = mmio_read_32(base + (8 * cpu) + REF_CLK_OFFSET);
+
+               /* return the counter values as two different parameters */
+               write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X1, core_clk_ctr);
+               write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X2, ref_clk_ctr);
+
+               return 0;
+
        default:
                break;
        }
index fe1c588485c406c9d61a07f55def26362573ec05..0c2b0a4703fae8fe27ffcc9ac790fcf62919c6a3 100644 (file)
@@ -57,10 +57,10 @@ $(eval $(call add_define,PLATFORM_CLUSTER_COUNT))
 PLATFORM_MAX_CPUS_PER_CLUSTER          := 4
 $(eval $(call add_define,PLATFORM_MAX_CPUS_PER_CLUSTER))
 
-MAX_XLAT_TABLES                                := 20
+MAX_XLAT_TABLES                                := 24
 $(eval $(call add_define,MAX_XLAT_TABLES))
 
-MAX_MMAP_REGIONS                       := 20
+MAX_MMAP_REGIONS                       := 24
 $(eval $(call add_define,MAX_MMAP_REGIONS))
 
 # platform files